<template>
  <div class="role-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>角色管理</span>
          <el-button type="primary" @click="handleAdd" v-permission="'system:role:add'">新增角色</el-button>
        </div>
      </template>
      <el-input v-model="roleName" placeholder="请输入菜单名称"
                style="width: 200px; margin-bottom: 10px; margin-right: 10px"/>
      <el-button type="danger" style="margin-bottom: 10px;" @click="search">搜索</el-button>
      <el-button type="info" style="margin-bottom: 10px;" @click="reSet">重置</el-button>
      <el-table :data="roleList" style="width: 100%" border>
        <el-table-column type="index" label="序号" width="60" fixed align="center"/>
        <el-table-column prop="roleName" label="角色名称" align="center"/>
        <el-table-column prop="roleKey" label="角色标识" align="center"/>
        <el-table-column prop="roleSort" label="排序" align="center"/>
        <el-table-column prop="status" label="状态" align="center">
          <template #default="{ row }">
            <el-tag :type="row.status === 1 ? 'success' : 'danger'">
              {{ row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="250" align="center">
          <template #default="{ row }">
            <el-button type="primary" link @click="handleEdit(row)" v-permission="'system:role:edit'">编辑</el-button>
            <el-button type="primary" link @click="handlePermission(row)" v-permission="'system:role:auth'">权限设置
            </el-button>
            <el-button v-if="row.roleKey !== 'admin'" type="primary" link @click="handleDelete(row)"
                       v-permission="'system:role:delete'">删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
          v-model:current-page="pageNum"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :small="false"
          :disabled="false"
          :background="true"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </el-card>

    <!-- 新增/编辑角色对话框 -->
    <el-dialog
        v-model="dialogVisible"
        :title="dialogType === 'add' ? '新增角色' : '编辑角色'"
        width="500px"
    >
      <el-form
          ref="formRef"
          :model="form"
          :rules="rules"
          label-width="100px"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="form.roleName" placeholder="请输入角色名称"/>
        </el-form-item>
        <el-form-item label="角色标识" prop="roleKey">
          <el-input v-model="form.roleKey" placeholder="请输入角色标识"/>
        </el-form-item>
        <el-form-item label="排序" prop="roleSort">
          <el-input-number v-model="form.roleSort" :min="0" :max="999"/>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="form.status">
            <el-radio :label="1">启用</el-radio>
            <el-radio :label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 权限设置对话框 (占位符) -->
    <el-dialog
        v-model="permissionDialogVisible"
        title="权限设置"
        width="500px"
    >
      <el-tree
          :data="menuList"
          show-checkbox
          node-key="id"
          :props="defaultProps"
          ref="menuTreeRef"
          check-strictly
      />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="permissionDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSavePermission">确定</el-button>
        </span>
      </template>
    </el-dialog>

  </div>
</template>

<script setup lang="ts">
import {ref, onMounted, nextTick} from 'vue'
import {ElMessage, ElMessageBox, type FormInstance} from 'element-plus'
import {getRolePage, addRole, updateRole, deleteRole, getRoleMenuIds, updateRoleMenus} from '@/api/role'
import {getAllMenuList} from '@/api/menu'

const roleList = ref<any>([])
const total = ref(0)
const pageNum = ref(1)
const pageSize = ref(10)
const dialogVisible = ref(false)
const dialogType = ref<'add' | 'edit'>('add')
const formRef = ref<FormInstance>()
const permissionDialogVisible = ref(false)
const menuTreeRef = ref()
const menuList = ref<any>([])
const currentRoleId = ref<number | undefined>(undefined)

const form = ref({
  id: undefined,
  roleName: '',
  roleKey: '',
  roleSort: 0,
  status: 1
})

const rules = {
  roleName: [{required: true, message: '请输入角色名称', trigger: 'blur'}],
  roleKey: [{required: true, message: '请输入角色标识', trigger: 'blur'}]
}

const defaultProps = {
  children: 'children',
  label: 'name'
}

const roleName = ref<string>('')
const search = async () => {
  await fetchRoleList()
}
const reSet = async () => {
  roleName.value = ''
  await fetchRoleList()
}
const fetchRoleList = async () => {
  const res = await getRolePage({pageNum: pageNum.value, pageSize: pageSize.value, roleName: roleName.value})
  if (res.code === 200) {
    roleList.value = res.data.records
    total.value = res.data.total
  }
}

const handleSizeChange = (val: number) => {
  pageSize.value = val
  fetchRoleList()
}

const handleCurrentChange = (val: number) => {
  pageNum.value = val
  fetchRoleList()
}

const resetForm = () => {
  form.value = {
    id: undefined,
    roleName: '',
    roleKey: '',
    roleSort: 0,
    status: 1
  }
  formRef.value?.resetFields()
}

const handleAdd = () => {
  dialogType.value = 'add'
  resetForm()
  dialogVisible.value = true
}

const handleEdit = (row: any) => {
  dialogType.value = 'edit'
  form.value = {...row}
  dialogVisible.value = true
}

const handleDelete = (row: any) => {
  ElMessageBox.confirm('确认要删除该角色吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    const res = await deleteRole(row.id)
    if (res.code === 200) {
      ElMessage.success('删除成功')
      await fetchRoleList()
    } else {
      ElMessage.error(res.msg || '删除失败')
    }
  }).catch(() => {
  })
}

const handleSubmit = async () => {
  if (!formRef.value) return
  await formRef.value.validate(async (valid) => {
    if (valid) {
      const api = dialogType.value === 'add' ? addRole : updateRole
      const res = await api(form.value)
      if (res.code === 200) {
        ElMessage.success(dialogType.value === 'add' ? '新增成功' : '编辑成功')
        dialogVisible.value = false
        await fetchRoleList()
      } else {
        ElMessage.error(res.msg || (dialogType.value === 'add' ? '新增失败' : '编辑失败'))
      }
    }
  })
}

const handlePermission = async (row: any) => {
  currentRoleId.value = row.id;
  permissionDialogVisible.value = true;

  const allMenusRes = await getAllMenuList();
  if (allMenusRes.code === 200) {
    menuList.value = allMenusRes.data;
  }

  const roleMenuIdsRes = await getRoleMenuIds(row.id);
  if (roleMenuIdsRes.code === 200) {
    await nextTick();
    menuTreeRef.value.setCheckedKeys(roleMenuIdsRes.data, false);
  }
}

const handleSavePermission = async () => {
  if (!menuTreeRef.value) return;

  const checkedKeys = menuTreeRef.value.getCheckedKeys();
  const halfCheckedKeys = menuTreeRef.value.getHalfCheckedKeys();
  const allSelectedKeys = [...checkedKeys, ...halfCheckedKeys];

  if (currentRoleId.value) {
    const res = await updateRoleMenus(currentRoleId.value, allSelectedKeys);
    if (res.code === 200) {
      ElMessage.success('权限设置成功');
      permissionDialogVisible.value = false;
    } else {
      ElMessage.error(res.msg || '权限设置失败');
    }
  }
};

onMounted(async () => {
  await fetchRoleList()
})
</script>

<style scoped>
.role-container {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.el-pagination {
  margin-top: 20px;
  justify-content: flex-end;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>
